import { Injectable } from '@angular/core';
import { Action, State, StateContext, Store } from '@ngxs/store';
import { BookAction } from '.';
import { BookService } from './book.service';
import { mergeMap, tap } from 'rxjs';
import { PageAction, PageSelector } from '../page';
import * as _ from 'lodash';
import * as immutable from 'immutable';
import { Navigate } from '@ngxs/router-plugin';

export interface BookStateModel {
  list: any[];
  editForm?: any;
}

@State<BookStateModel>({
  name: 'book',
  defaults: {
    list: [],
  },
})
@Injectable({
  providedIn: 'root',
})
export class BookState {

  constructor(
      private store: Store,
      private service: BookService,
  ) {
  }

  @Action(BookAction.RefreshData)
  RefreshData(ctx: StateContext<BookStateModel>) {
    const page = this.store.selectSnapshot(PageSelector.page);
    return this.service.refreshData(page).pipe(tap((r: any) => {
      ctx.patchState({list: r.result});
    }), mergeMap((r) => ctx.dispatch(new PageAction.ChangeCount(r.count))));
  }

  @Action(BookAction.Collect)
  Collect(ctx: StateContext<BookStateModel>, payload: BookAction.Collect) {
    return this.service.collect(payload.item.id).pipe(tap(() => {
      const idx = _.findIndex(ctx.getState().list, s => s.id === payload.item.id);
      const state = immutable.setIn(ctx.getState(), ['list', idx, 'isCollect'], !payload.item.isCollect);
      ctx.patchState(state);
    }));
  }

  @Action(BookAction.Edit)
  Edit(ctx: StateContext<BookStateModel>, payload: BookAction.Edit) {
    ctx.patchState(immutable.setIn(ctx.getState(), ['editForm', 'model'], payload.item));
    return ctx.dispatch(new Navigate([`/book/edit`]));
  }

  @Action(BookAction.Save)
  Save(ctx: StateContext<BookStateModel>) {
    if (ctx.getState().editForm.invalid) {
      return;
    }
    return this.service.save(ctx.getState().editForm.model)
        .pipe(mergeMap(() => ctx.dispatch(new BookAction.RefreshData())));
  }

}
